﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace SharePointHelper.DLL.SSOM
{
	public class Cache
    {
        #region 格式化key
        /// <summary>
        /// 格式化key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
		public static string FormatKey(string key)
		{
			if (!string.IsNullOrEmpty(key))
			{
				// 转化成小写并且去掉首尾空行
				key = key.ToLower().Trim();

                // 移除清除缓存的URL参数
				key = key.Replace("&isclearcache=true", "").Replace("?isclearcache=true", "").Replace("&isclearcache=false", "").Replace("?isclearcache=false", "");
			}
			return key;
		}
        #endregion

        #region 判断缓存中有没有这个key
        /// <summary>
		/// 判断缓存中有没有这个key
		/// </summary>
		/// <param name="current"></param>
		/// <param name="key"></param>
		/// <returns></returns>
		public static bool IsExist(System.Web.Caching.Cache cache, string key)
		{
			bool isExist = false;
			try
			{
				// 初始化
				if (cache == null) { throw new Exception("Cache passed is null"); }
				if (string.IsNullOrEmpty(key)) { throw new Exception("Cache key passed is null"); }
				string _key = FormatKey(key);


				if (cache != null && cache[_key] != null)
				{
					isExist = true;
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("fdgghcghcxdfft", ex, "key: " + key);
			}
			return isExist;
		}
        #endregion

        #region 根据key获取缓存中的数据
        /// <summary>
		/// 根据key获取缓存中的数据
		/// </summary>
		/// <param name="current"></param>
		/// <param name="key"></param>
		/// <returns></returns>
		public static string GetCache(System.Web.Caching.Cache cache, string key)
		{
			string o = null;
			try
			{
				// 初始化
				if (cache == null) { throw new Exception("Cache passed is null"); }
				if (string.IsNullOrEmpty(key)) { throw new Exception("Cache key passed is null"); }
				string _key = FormatKey(key);


				if (IsExist(cache, _key))
				{
					o = cache[_key].ToString();
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("dxfvhjyutu6deswawwaes", ex, "key: " + key);
				o = null;
			}
			return o;
		}
        #endregion

        #region 获取cache中包含某个key的集合
        /// <summary>
		/// 获取cache中包含某个key的集合
		/// </summary>
		/// <param name="cache"></param>
		/// <param name="keySubstring"></param>
		/// <returns></returns>
		public static Dictionary<string, object> GetCacheCollection(System.Web.Caching.Cache cache, string keySubstring)
		{
			Dictionary<string, object> cacheCollection = null;
			try
			{
				// 初始化
				if (!string.IsNullOrEmpty(keySubstring)) { keySubstring = keySubstring.ToLower().Trim(); }
				cacheCollection = new Dictionary<string,object>();


				if (cache != null)
				{
					int loopCheck = 0; int maxLoop = 100000;
					System.Collections.IDictionaryEnumerator _cache = cache.GetEnumerator();
					while (_cache.MoveNext())
					{
						if (loopCheck > maxLoop) { break; }
						loopCheck++;

						string currentKey = _cache.Key.ToString();
						if (string.IsNullOrEmpty(keySubstring) || currentKey.ToLower().Contains(keySubstring))
						{
							cacheCollection.Add(currentKey, cache[currentKey]);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("tdhrtytrjshew5thnddzfzdg", ex);
				cacheCollection = null;
			}
			return cacheCollection;
		}
        #endregion

        #region 添加string数据到缓存中， 会覆盖已经存在的这个key的数据
        /// <summary>
		/// 添加string数据到缓存中， 会覆盖已经存在的这个key的数据
		/// </summary>
		/// <param name="current"></param>
		/// <param name="key"></param>
		/// <param name="valueToCache"></param>
		/// <param name="numberOfMinutesToCache"></param>
		public static void AddCache(System.Web.Caching.Cache cache, string key, string valueToCache, 
			int numberOfMinutesToCache)
		{
			try
			{
				// 初始化
				if (cache == null) { throw new Exception("Cache passed is null"); }
				if (string.IsNullOrEmpty(key)) { throw new Exception("Cache key passed is null"); }
				if (numberOfMinutesToCache == 0) { numberOfMinutesToCache = 15; }
				string _key = FormatKey(key);


				if (IsExist(cache, _key))
				{
					// 移除已经存在的key的数据
					cache.Remove(_key);
				}

				cache.Add(_key, valueToCache, null, DateTime.Now.AddMinutes(numberOfMinutesToCache),
					System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal,
					null);
			}
			catch (Exception ex)
			{
				Log.WriteError("u8oydtsdrgsaasee", ex, "key: " + key);
			}
		}
        #endregion

        #region 删除缓存中的指定数据
        /// <summary>
		/// 删除缓存中的指定数据
		/// </summary>
		/// <param name="current"></param>
		/// <param name="keySubstring">比如, 如果要删除一个site collection所有缓存的页面, 输入域名称</param>
		/// <returns>返回删除了多少条数据的数量</returns>
		public static int DeleteCache(System.Web.Caching.Cache cache, string keySubstring)
		{
			int numberItemsDeleted = 0;
			try
			{
				// 初始化
				if (cache == null) { throw new Exception("Cache passed is null"); }
				if (string.IsNullOrEmpty(keySubstring)) { throw new Exception("Cache key substring passed is null"); }
				keySubstring = keySubstring.ToLower().Trim();


				// 获取所有匹配的缓存
				Dictionary<string, object> cacheToDelete = GetCacheCollection(cache, keySubstring);

				// 删除缓存
				foreach (KeyValuePair<string, object> c in cacheToDelete)
				{
					cache.Remove(c.Key);
					numberItemsDeleted++;
				}
				
			}
			catch (Exception ex)
			{
				Log.WriteError("67irraewwaawwarzdxfhxft", ex, "key substring: " + keySubstring);	
			}
			return numberItemsDeleted;
		}
        #endregion

        #region 判断是否需要重新创建缓存（判断缓存是否被清除）
        /// <summary>
		/// 判断是否需要重新创建缓存（判断缓存是否被清除）
		/// </summary>
		/// <param name="cache"></param>
		/// <param name="cacheKey"></param>
		/// <param name="fullUrl"></param>
		/// <returns></returns>
		public static bool IsClearCache(System.Web.Caching.Cache cache, string cacheKey, string fullUrl)
		{
			bool isRecreateCache = true;
			bool isDebug = false;
			try
			{
				// 初始化
				if (cache != null && !string.IsNullOrEmpty(cacheKey) && !string.IsNullOrEmpty(fullUrl))
				{
					if (isDebug) { Log.WriteInformation("starting to check cache info, key: " + cacheKey + " full url: " + fullUrl); }

                    // url 中是否有对应参数（isclearcache）
					if (fullUrl.ToLower().Contains("isclearcache"))
					{
						if (isDebug) { Log.WriteInformation("is clear cache param defined"); }
						isRecreateCache = Convert.ToBoolean(Utilities.GetUrlParamValue("isclearcache", fullUrl));
						if (isDebug) { Log.WriteInformation("isClearCache param value is: " + isRecreateCache + " with param value string:" + Utilities.GetUrlParamValue("isclearcache", fullUrl)); }
                        // 参数的值为false，没有缓存的存在，强制重新缓存
						if (!isRecreateCache && !IsExist(cache, cacheKey))  
						{ 
							isRecreateCache = true;
							if (isDebug) { Log.WriteInformation("isClearCache param value is false, yet cached info doesn't already exist. Will force page to create new cache entry"); }
						}
					}
					// 判断缓存是否存在
					else if (IsExist(cache, cacheKey)) 
					{
						isRecreateCache = false;
						if (isDebug) { Log.WriteInformation("isClearCache url param not passed, and content already cached. Will use cache"); }
					}
				}

				// 不用作任何缓存 on edit form
				if (!string.IsNullOrEmpty(fullUrl) && fullUrl.ToLower().Contains("editform.aspx"))
				{
					isRecreateCache = false;
					if (isDebug) { Log.WriteInformation("Edit form, will force content to use what is cached or nothing at all"); }
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("6r7irthsrsaaewraew", ex, " cache key: " + cacheKey + " url: " + fullUrl);
			}
			return isRecreateCache;
        }
        #endregion

    }
}
